package chpt_06_04_visitor;

import java.util.List;

/**
 * @author Ping
 * @date 2023/5/25 10:45
 **/
public class VisitorDemo {

    public static void main(String args[]) {
        /**
         * object structure
         */
        Park park = new Park() ;
        TravelVisitor child = new Child() ;
        TravelVisitor oldman = new OldMan() ;
        park.accept(child);
        park.accept(oldman);



    }

}

interface TravelVisitor {
    public void travelLaker(Laker laker) ;
    public void travelStatus(Status status) ;
    public void travelForest(Forest forest) ;

}

/**
 * abstract element
 */
interface TravellingView {
    public String getName() ;
    public void travelBy(TravelVisitor visitor) ;
}

/**
 * concrete elements
 */
class Laker implements TravellingView {
    @Override
    public String getName() {
        return "GREAT LAKER" ;
    }

    @Override
    public void travelBy(TravelVisitor visitor) {
        visitor.travelLaker(this);
    }
}

class Status implements TravellingView {
    @Override
    public String getName() {
        return "GOOD STATUS";
    }

    @Override
    public void travelBy(TravelVisitor visitor) {
        visitor.travelStatus(this);
    }
}

class Forest implements TravellingView {
    @Override
    public String getName() {
        return "BLACK FOREST";
    }

    @Override
    public void travelBy(TravelVisitor visitor) {
        visitor.travelForest(this);
    }
}

/**
 * element structure
 */
class Park {
    private List<TravellingView> travellingViews ;

    public Park() {
        this.travellingViews = List.of(new Laker(),
                                        new Status(),
                                        new Forest()) ;
    }

    public void accept(TravelVisitor visitor) {
        this.travellingViews.forEach(view -> view.travelBy(visitor));
    }
}

/**
 * the core of Visitor Pattern: various of visitors
 */
class Child implements TravelVisitor {
    @Override
    public void travelLaker(Laker laker) {
        System.out.println("Child visit "
                + laker.getName() + ": Very GOOD") ;
    }

    @Override
    public void travelStatus(Status status) {
        System.out.println("Child visit "
                + status.getName() + ": Too OLD") ;
    }

    @Override
    public void travelForest(Forest forest) {
        System.out.println("Child visit "
                + forest.getName() + ": Very Excited! ") ;
    }
}

class OldMan implements TravelVisitor {
    @Override
    public void travelLaker(Laker laker) {
        System.out.println("Oldman visit "
                + laker.getName() + ": Very GOOD") ;
    }

    @Override
    public void travelStatus(Status status) {
        System.out.println("Oldman visit "
                + status.getName() + ": Very Impressive") ;
    }

    @Override
    public void travelForest(Forest forest) {
        System.out.println("Oldman visit "
                + forest.getName() + ": Very QUITE") ;
    }
}


